//
//  OFEngine.m
//  PUDemo
//
//  Created by JK.Peng on 13-2-22.
//  Copyright (c) 2013年 njut. All rights reserved.
//

#import "OFEngine.h"

@implementation OFEngine
@synthesize appKey = _appKey;
@synthesize appSecret = _appSecret;
@synthesize authorize = _authorize;
@synthesize delegate = _delegate;

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kNotificationWBAuthorizeChanged object:nil];
    [_appKey release], _appKey = nil;
    [_appSecret release], _appSecret = nil;
    [_authorize release], _authorize = nil;
    for (OFRequest * request in _requestAry) {
        request.delegate = nil;
    }
    [_requestAry release], _requestAry = nil;
    [super dealloc];
}

- (id)initWithAppKey:(NSString *)theAppKey
           appSecret:(NSString *)theAppSecret
            oauthVer:(OFOauthVer)theOauthVer
                type:(OFTypeE)type
{
    self = [super init];
    if (self){
        self.appKey = theAppKey;
        self.appSecret = theAppSecret;
        _oauthVer = theOauthVer;
        _type = type;
        _requestAry = [[NSMutableArray alloc] initWithCapacity:0];
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(readAuthorizeData)
                                                     name:kNotificationWBAuthorizeChanged
                                                   object:nil];
        [self readAuthorizeData];
    }
    return self;
}

#pragma mark Authorization

- (void)logIn
{
    if ([self isLoggedIn])
    {
        [self delegateEngineAlreadyLoggedIn];
        return;
    }
    
    if (self.authorize) {
        return;
    }
    
    [self startAuthorize];
}

- (void)logOut
{
    [self deleteAuthorizeData];
    [self delegateEngineDidLogOut];
}

- (BOOL)isLoggedIn
{
    // Should be implemented in subclass
    return NO;
}

- (BOOL)isAuthorizeExpired
{
    return NO;
}

#pragma mark - Request
- (void)loadRequestWithUrl:(NSString *)url
                httpMethod:(NSString *)httpMethod
                    params:(NSDictionary *)params
              postDataType:(OFRequestPostDataType)postDataType
          httpHeaderFields:(NSDictionary *)httpHeaderFields
{
    // Step 1.
    // Check if the user has been logged in.
	if (![self isLoggedIn])
	{
        [self delegateEngineNotAuthorized];
        return;
	}
    
	// Step 2.
    // Check if the access token is expired.
    if ([self isAuthorizeExpired])
    {
        [self delegateEngineAuthorizeExpired];
        return;
    }
    
    NSMutableDictionary * paramsM = [NSMutableDictionary dictionaryWithDictionary:params];
    OFRequest * request = [self generateRequestWithUrl:url
                                            httpMethod:httpMethod
                                                params:paramsM
                                          postDataType:postDataType
                                      httpHeaderFields:httpHeaderFields
                                              delegate:self];
	if (request) {
        [_requestAry addObject:request];
        [request connect];
    } else {
        [self delegateEngineRequestDidFailWithError:nil];
    }
}


- (void)loadApiKeyRequestWithUrl:(NSString *)url httpMethod:(NSString *)httpMethod params:(NSDictionary *)params postDataType:(OFRequestPostDataType)postDataType httpHeaderFields:(NSDictionary *)httpHeaderFields{
    
    NSMutableDictionary * paramsM = [NSMutableDictionary dictionaryWithDictionary:params];
    OFRequest * request = [self generateRequestWithUrl:url
                                            httpMethod:httpMethod
                                                params:paramsM
                                          postDataType:postDataType
                                      httpHeaderFields:httpHeaderFields
                                              delegate:self];
	if (request) {
        [_requestAry addObject:request];
        [request connect];
    } else {
        [self delegateEngineRequestDidFailWithError:nil];
    }
}
- (void)cancelRequest
{
    [self retain];
    for (OFRequest * request in _requestAry) {
        request.delegate = nil;
        [request disconnect];
    }
    [_requestAry removeAllObjects];
    [self release];
}

#pragma mark - OFAuthorizeDelegate Methods
- (void)authorizeDidSuccee:(OFAuthorize *)authorize
{
    [self retain];
    self.authorize.delegate = nil;
    self.authorize = nil;
    [self saveAuthorizeData];
    [self delegateEngineDidLogIn];
    [self release];
}

- (void)authorize:(OFAuthorize *)authorize didFailWithError:(NSError *)error
{
    [self retain];
    self.authorize.delegate = nil;
    self.authorize = nil;
    [self delegateEngineDidFailToLogInWithError:error];
    [self release];
}

#pragma mark - OFRequestDelegate Methods
- (void)request:(OFRequest *)request didFinishLoadingWithResult:(NSString *)result
{
    [self retain];
    request.delegate = nil;
    [_requestAry removeObjectIdenticalTo:request];
    NSError * error = nil;
    NSDictionary * jsonDict = [self parseJSONString:result error:&error];
    if (!error) {
        [self delegateEngineRequestDidSucceedWithResult:jsonDict];
    } else {
        [self delegateEngineRequestDidFailWithError:error];
    }
    [self release];
}

- (void)request:(OFRequest *)request didFailWithError:(NSError *)error
{
    [self retain];
    [_requestAry removeObjectIdenticalTo:request];
    [self delegateEngineRequestDidFailWithError:error];
    [self release];
}

#pragma mark - Private
- (void)startAuthorize
{
    // Should be overwroten in subclass
    [self delegateEngineDidFailToLogInWithError:nil];
}

- (OFRequest *)generateRequestWithUrl:(NSString *)url
                           httpMethod:(NSString *)httpMethod
                               params:(NSMutableDictionary *)params
                         postDataType:(OFRequestPostDataType)postDataType
                     httpHeaderFields:(NSDictionary *)httpHeaderFields
                             delegate:(id<OFRequestDelegate>)delegate
{
    return nil;
}

- (NSString *)urlSchemeString
{
    return [NSString stringWithFormat:@"OPF_TYPE%d_OAUTH%d_%@_OPFServiceName", _type, _oauthVer, _appKey];
}

- (void)saveAuthorizeData
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationWBAuthorizeChanged object:self];
}

- (void)readAuthorizeData
{
    return;
}

- (void)deleteAuthorizeData
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotificationWBAuthorizeChanged object:self];
}

- (id)parseJSONString:(NSString *)string error:(NSError **)error
{
	SBJSON *jsonParser = [[SBJSON alloc]init];
	
	NSError *parseError = nil;
	id result = [jsonParser objectWithString:string error:&parseError];
	
	if (parseError) {
        if (error != nil) {
            *error = [NSError errorWithDomain:kOFSDKErrorDomain
                                         code:kOFErrorCodeSDK
                                     userInfo:[NSDictionary dictionaryWithObject:[NSString stringWithFormat:
                                                                                  @"%d", kOFSDKErrorCodeParseError]
                                                                          forKey:kOFSDKErrorCodeKey]];
        }
	}
    
	[jsonParser release];
	return result;
}

- (void)delegateEngineAlreadyLoggedIn
{
    if ([_delegate respondsToSelector:@selector(engineAlreadyLoggedIn:)]) {
        [_delegate engineAlreadyLoggedIn:self];
    }
}

- (void)delegateEngineDidLogIn
{
    if ([_delegate respondsToSelector:@selector(engineDidLogIn:)]) {
        [_delegate engineDidLogIn:self];
    }
}

- (void)delegateEngineDidFailToLogInWithError:(NSError *)error
{
    if ([_delegate respondsToSelector:@selector(engine:didFailToLogInWithError:)]) {
        [_delegate engine:self didFailToLogInWithError:error];
    }
}

- (void)delegateEngineDidLogOut
{
    if ([_delegate respondsToSelector:@selector(engineDidLogOut:)]) {
        [_delegate engineDidLogOut:self];
    }
}

- (void)delegateEngineNotAuthorized
{
    if ([_delegate respondsToSelector:@selector(engineNotAuthorized:)]) {
        [_delegate engineNotAuthorized:self];
    }
}

- (void)delegateEngineAuthorizeExpired
{
    [self deleteAuthorizeData];
    if ([_delegate respondsToSelector:@selector(engineAuthorizeExpired:)]) {
        [_delegate engineAuthorizeExpired:self];
    }
}

- (void)delegateEngineRequestDidFailWithError:(NSError *)error
{
    if ([_delegate respondsToSelector:@selector(engine:requestDidFailWithError:)]) {
        [_delegate engine:self requestDidFailWithError:error];
    }
}

- (void)delegateEngineRequestDidSucceedWithResult:(id)result
{
    if ([_delegate respondsToSelector:@selector(engine:requestDidSucceedWithResult:)]) {
        [_delegate engine:self requestDidSucceedWithResult:result];
    }
}

#pragma mark - API
- (void)repostWeiboWithWeiboId:(NSString *)weiboId
                          text:(NSString *)text
                   commentType:(OFRepostCommentType)commentType
{

}

- (void)sendWeiBoWithText:(NSString *)text image:(UIImage *)image
{

}

- (void)sendCommentWithWeiboId:(NSString *)weiboId
                          text:(NSString *)text
                    commentOri:(BOOL)commentOri
{
}
@end
